package maskedpixel.ogmo.utils 
{
	import flash.utils.*;
	
	/**
	 * ...
	 * @author Erin M Gunn
	 */
	public class OgmoObject
	{
		/**
		 * The class name that will load this layer, including the class's package.
		 */
		public var cName:String;
		
		/**
		 * The name of this object.
		 */
		public var name:String;
		
		/**
		 * The image that Ogmo will use to draw this object.
		 */
		public var image:String;
		
		/**
		 * width of this object.
		 */
		public var width:uint;
		
		/**
		 * height of this object.
		 */
		public var height:uint;
		
		
		
		/**
		 * Constructor.
		 * @param	name	Name of this Object.
		 * @param	image	A string containing the location and name of the image file to use.
		 * @param	width	The width of the image.
		 * @param	height	The height of the image.
		 */
		public function OgmoObject(cName:String, name:String, image:String, width:uint, height:uint) 
		{
			this.cName = cName;
			this.name = name;
			this.image = image;
			this.width = width;
			this.height = height;
		}
		
		/**
		 * Generate the xML representing this object in the ogmo project file.
		 * @return
		 */
		public function generateXML():XML
		{
			var xml:XML = new XML();
			xml = <object/>;
			xml.@name = name;
			xml.@image = image;
			xml.@width = width;
			xml.@height = height;
			for each(var attribute:OgmoAttribute in _attributeList)
			{
				xml.@[attribute.name] = attribute.value;
			}
			for each(var value:OgmoValue in _valueList)
			{
				xml.values.*[xml.values.children().length()] = value.generateXML();
			}
			if (_node)
			{
				xml.*[xml.children().length()] = _node.generateXML();
			}
			return xml;
		}
		
		/**
		 * Load the class associated with this object.
		 * @param	clsRef			A reference to the class definition. This is class agnostic.
		 * @param	dataElement		The xml that pertains to this object.
		 * @return					A new Object with all data imported.
		 */
		public function loadFromXML(clsRef:Class, dataElement:XML):Object
		{
			var e:Object = new clsRef();
			// Set the fields of e to the value of the attributes in the dataElement.
			for (var i:uint = 0; i < dataElement.attributes().length(); i++ )
			{
				if (e.hasOwnProperty(dataElement.attributes()[i].name()))
				{
					e[dataElement.attributes()[i].name().toString()] = dataElement.attributes()[i];
				}
			}
			
			// Set all the values registered with ogmo.
			for each(var value:OgmoValue in _valueList)
			{
				// if the value exists in the entity, asign it.
				if (e.hasOwnProperty(value.name))
				{
					e[value.name] = dataElement.attribute(value.name);
				}
			}
			
			return e;
		}
		
		/**
		 * Register an OgmoAttribute with this object.
		 * @param	...attributes	Any of an OgmoAttribute, a Vector.<OgmoAttribute>,
		 * 							or an Array of OgmoAttribute's.
		 */
		public function registerAttribute(...attributes):void
		{
			for each(var attribute:Object in attributes)
			{
				if (attribute is OgmoAttribute)
				{
					if (_attributeList.indexOf(attribute) == -1)
					{
						_attributeList.push(attribute);
					}
				}
				if (attribute is Vector.<OgmoAttribute> || attribute is Array)
				{
					for each(var att:OgmoAttribute in attribute)
					{
						if (_attributeList.indexOf(att) == -1)
						{
							_attributeList.push(att);
						}
					}
				}
			}
		}
		
		/**
		 * Register an OgmoValue with this object.
		 * @param	...values	Any of an OgmoValue, a Vector.<OgmoValue>,
		 * 						or an Array of OgmoValue's.
		 */
		public function registerValue(...values):void
		{
			for each(var value:Object in values)
			{
				if (value is OgmoValue)
				{
					if (_valueList.indexOf(value) == -1)
					{
						_valueList.push(value);
					}
				}
				if (value is Vector.<OgmoValue> || value is Array)
				{
					for each(var val:OgmoValue in value)
					{
						if (_valueList.indexOf(value) == -1)
						{
							_valueList.push(value);
						}
					}
				}
			}
		}
		
		/**
		 * Register a node with this object.
		 * @param	node	The OgmoNode to register.
		 */
		public function registerNode(node:OgmoNode):void
		{
			if (_node == node)	return;
			_node = node;
		}
		
		// Properties used by Ogmo Editor.
		/** @private */ private var _attributeList:Vector.<OgmoAttribute> = new Vector.<OgmoAttribute>();
		/** @private */ private var _valueList:Vector.<OgmoValue> = new Vector.<OgmoValue>();
		/** @private */ private var _node:OgmoNode;
	}

}